package pers.cz.parser.start;

import cn.hutool.*;
import info.monitorenter.cpdetector.io.*;
import net.sf.jsqlparser.JSQLParserException;
import net.sf.jsqlparser.statement.insert.Insert;
import pers.cz.parser.config.GenerateDeleteType;
import pers.cz.parser.config.SqlType;
import pers.cz.parser.tools.SqlParserTool;

import java.io.*;
import java.nio.charset.Charset;
import java.util.ArrayList;
import java.util.List;

/**
 * @program: parser
 * @description: Main
 * @author: Cheng Zhi
 * @create: 2021-05-28 09:46
 **/
public class Main {

    private static List<File> fileList = new ArrayList<File>();
    public static void main(String[] args) throws Exception {
        String path = "D:\\scripts";
        // 删除回退脚本
        // deleteRollBackeFile(path);
        // 生成回退脚本
        GenerateFile(path, GenerateDeleteType.ByPrimaryKey);
        // 合并回退脚本
        // mergeFile(path);
    }

    /**
     * 将文件名称相同的文件合并
     */
    private static void mergeFile(String path) throws IOException {
        readFile(path);
        File fileRollBack = new File(path + "all-test.sql");
        BufferedReader reader = null;
        FileWriter writer = new FileWriter(fileRollBack.getName());
        BufferedWriter bw = new BufferedWriter(writer);

        for (File file : fileList) {
            if (file.getName().endsWith(".sql")) {
                reader = new BufferedReader(new FileReader(file));
                String tempStr;
                while ((tempStr = reader.readLine()) != null) {
                    bw.write(tempStr);
                    bw.newLine();
                    //writeTempFile1(fileRollBack, tempStr);
                }
                reader.close();
            }
        }

        bw.close();
        writer.close();
    }
    /**
     * 删除文件
     */
    private static void deleteRollBackeFile(String path) {
        readFile(path);

        for (File file : fileList) {
            if (file.getName().contains("_rollBack")) {
                file.delete();
            }
        }
    }

    /**
     * 操作文件,生成回退语句，并命名为xxxx.sql_rollBack
     * @throws IOException
     */
    private static void GenerateFile(String path, GenerateDeleteType type) throws Exception {
        readFile(path);

        for (File file : fileList) {
            System.out.println(file.getName());
            if (file.getName().contains(".sql")) {
                BufferedReader reader = null;
                File fileRollBack = new File(file.getPath()+"_rollBack");
                FileWriter writer = new FileWriter(file.getPath() + "_rollBack");
                BufferedWriter bw = new BufferedWriter(writer);
                StringBuffer sbf = new StringBuffer();
                String charSet = getFileCharset(file);
                InputStreamReader isReader = new InputStreamReader(new FileInputStream(file), charSet);
                try {
                    reader = new BufferedReader(isReader);
                    String tempStr;
                    while ((tempStr = reader.readLine()) != null) {
                        if (tempStr.toLowerCase().contains("insert")) {
                            SqlType sqlType = SqlParserTool.getSqlType(tempStr);
                            if (sqlType.equals(SqlType.INSERT)) {
                                Insert statement = (Insert) SqlParserTool.getStatement(tempStr);
                                String deleteSql = "";
                                if (type.equals(GenerateDeleteType.ByAllColumns)){
                                    deleteSql = SqlParserTool.insertToDelete(statement);
                                }else{
                                    deleteSql = SqlParserTool.insertToDeleteByPrimaryKey(statement);
                                }
                                System.out.println(deleteSql);
                                bw.write(deleteSql);
                                bw.newLine();
                            }
                        }
                        System.out.println(sbf.toString());
                    }
                    reader.close();
                    bw.close();
                    writer.close();

                } catch (IOException e) {
                    e.printStackTrace();
                } catch (JSQLParserException e) {
                    e.printStackTrace();
                } finally {
                    if (reader != null) {
                        try {
                            reader.close();
                        } catch (IOException e1) {
                            e1.printStackTrace();
                        }
                    }
                }
            }
        }
    }


    private static String getFileCharset(File file) throws Exception {
        CodepageDetectorProxy detector = CodepageDetectorProxy.getInstance();
        detector.add(new ParsingDetector(false));
        detector.add(JChardetFacade.getInstance());
        detector.add(ASCIIDetector.getInstance());
        detector.add(UnicodeDetector.getInstance());
        Charset charset = null;
        try {
            charset = detector.detectCodepage(file.toURI().toURL());
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        }
        String charsetName = "GBK";
        if (charset != null) {
            if (charset.name().equals("US-ASCII")) {
                charsetName = "ISO_8859_1";
            } else if (charset.name().startsWith("UTF")) {
                charsetName = charset.name();// 例如:UTF-8,UTF-16BE.
            }
        }
        return charsetName;
    }
    /**
     * 循环获取指定文件夹下的所有文件
     * @param path
     */
    private static void readFile(String path) {

        File filePath = new File(path);
        File[] list = filePath.listFiles();
        if(list!=null && list.length>0){
            for(int i=0; i<list.length; i++){
                File f = list[i];
                if(f.isFile() && !f.isHidden()){
                    fileList.add(f);
                }else if(f.isDirectory() && !f.isHidden()){
                    readFile(f.getPath());
                }
            }
        }
    }

    public static void writeTempFile1(File fileTemp,  String cline)
    {
        try {
            RandomAccessFile outStream = new RandomAccessFile(fileTemp, "rw");
            outStream.seek(outStream.length());
            outStream.write(cline.getBytes("GBK"));
            outStream.write("\r\n".getBytes());
            outStream.close();
        } catch (Exception e) {
            System.out.println(e.getMessage());
            // TODO: handle exception
        }
    }

}
